use crate::rtsp::rtp::rtcp::errors::RtcpError;
use crate::rtsp::rtp::rtcp::rtcp_header::RtcpHeader;
use crate::rtsp::rtp::utils::{Marshal, Unmarshal};
use byteorder::BigEndian;
use bytes::BytesMut;
use bytesio::bytes_reader::BytesReader;
use bytesio::bytes_writer::BytesWriter;
// 以下注释展示了 RTCP BYE 数据包的二进制结构，每一行代表 32 位（4 字节）
//  	  0                   1                   2                   3
//  	  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// 	     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// 	     |V=2|P|    SC   |   PT=BYE=203  |             length            |
// 	     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// 	     |                           SSRC/CSRC                           |
// 	     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// 	     :                              ...                              :
// 	     +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
// (opt) |     length    |            reason for leaving     ...
// 	     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

// RtcpBye 结构体，用于表示 RTCP BYE 类型的数据包
#[derive(Debug, Clone, Default)]
pub struct RtcpBye {
    // RTCP 头部
    pub header: RtcpHeader,
    // 同步源标识符
    pub ssrss: Vec<u32>,
    // 离开原因的长度
    pub length: u8,
    // 离开会话的原因，以字节形式存储
    pub reason: BytesMut,
}

impl Unmarshal<BytesMut, Result<Self, RtcpError>> for RtcpBye {
    fn unmarshal(data: BytesMut) -> Result<Self, RtcpError>
    where
        Self: Sized,
    {
        // 创建一个字节读取器，用于从可变字节缓冲区中读取数据
        let mut reader = BytesReader::new(data);

        // 创建一个 RtcpBye 实例，并从字节读取器中读取 RTCP 头部信息
        let mut rtcp_bye = RtcpBye {
            // 调用 RtcpHeader 的 unmarshal 方法解析 RTCP 头部
            header: RtcpHeader::unmarshal(&mut reader)?,
            // 其他字段使用默认值
            ..Default::default()
        };

        // 根据 RTCP 头部中的源计数（SC），循环读取相应数量的 SSRC/CSRC
        for _ in 0..rtcp_bye.header.report_count {
            // 以大端字节序读取 4 字节作为 SSRC/CSRC
            let ssrc = reader.read_u32::<BigEndian>()?;
            // 将读取到的 SSRC/CSRC 添加到 ssrss 向量中
            rtcp_bye.ssrss.push(ssrc);
        }

        // 读取离开原因的长度
        rtcp_bye.length = reader.read_u8()?;
        // 根据长度读取相应的离开原因字节数据
        rtcp_bye.reason = reader.read_bytes(rtcp_bye.length as usize)?;

        // 返回解析成功的 RtcpBye 实例
        Ok(rtcp_bye)
    }
}

impl Marshal<Result<BytesMut, RtcpError>> for RtcpBye {
    fn marshal(&self) -> Result<BytesMut, RtcpError> {
        // 创建一个默认的字节写入器
        let mut writer = BytesWriter::default();

        // 调用 RtcpHeader 的 marshal 方法将 RTCP 头部序列化为字节数据
        let header_bytesmut = self.header.marshal()?;
        // 将序列化后的 RTCP 头部字节数据写入字节写入器
        writer.write(&header_bytesmut[..])?;

        // 遍历 ssrss 向量，将每个 SSRC/CSRC 以大端字节序写入字节写入器
        for ssrc in &self.ssrss {
            writer.write_u32::<BigEndian>(*ssrc)?;
        }

        // 写入离开原因的长度
        writer.write_u8(self.length)?;
        // 写入离开原因的字节数据
        writer.write(&self.reason[..])?;

        // 提取字节写入器中的当前字节数据并返回
        Ok(writer.extract_current_bytes())
    }
}
